package xidian.vlab.service.impl;

import org.openstack4j.api.Builders;
import org.openstack4j.model.common.ActionResponse;
import org.openstack4j.model.common.Identifier;
import org.openstack4j.model.identity.v3.Project;
import org.openstack4j.model.identity.v3.User;
import org.openstack4j.openstack.OSFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import xidian.vlab.config.Properties;
import xidian.vlab.domin.Log;
import xidian.vlab.domin.User.Admin;
import xidian.vlab.domin.User.Student;
import xidian.vlab.domin.User.Teacher;
import xidian.vlab.dto.ListDTO;
import xidian.vlab.dto.QueryDTO;
import xidian.vlab.dto.ResJsonDTO;
import xidian.vlab.dto.UserDTO;
import xidian.vlab.repository.User.AdminRepository;
import xidian.vlab.repository.User.StudentRepository;
import xidian.vlab.repository.User.TeacherRepository;
import xidian.vlab.service.LogService;
import xidian.vlab.service.UserService;
import xidian.vlab.utils.ResUtil;
import xidian.vlab.utils.TokenUtil;
import org.openstack4j.api.OSClient.OSClientV3;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service("UserService")
public class UserServiceImpl implements UserService {
    @Autowired
    private AdminRepository admRepo;
    @Autowired
    private StudentRepository stuRepo;
    @Autowired
    private TeacherRepository tchRepo;
    @Autowired
    private LogService logService;
    @Autowired
    private Properties properties;

    @Override
    public ResJsonDTO login(UserDTO user) {
        String psw = user.getPassword();
        switch (user.getRole().charAt(0)) {
            case 'T':
                Teacher teacher = tchRepo.findById(user.getUid()).orElse(null);
                if (teacher == null || !teacher.getPassword().equals(psw)) break;
                user.setName(teacher.getName());
                logService.addLog(new Log(
                        teacher.getTid(),
                        teacher.getName(),
                        "登录",
                        "成功",
                        null,
                        new Date()
                ));
                System.out.println("Teacher:" + teacher.getName() + " login.");
                return ResUtil.OK(TokenUtil.createToken(user, "Teacher"));
            case 'S':
                Student student = stuRepo.findById(user.getUid()).orElse(null);
                if (student == null || !student.getPassword().equals(psw)) break;
                user.setName(student.getName());
                logService.addLog(new Log(
                        student.getSid(),
                        student.getName(),
                        "登录",
                        "成功",
                        null,
                        new Date()
                ));
                System.out.println("Student:" + student.getName() + " login.");
                return ResUtil.OK(TokenUtil.createToken(user, "Student"));
        }
        logService.addLog(new Log(
                user.getUid(),
                user.getName(),
                "登录",
                "失败",
                null,
                new Date()
        ));
        System.out.println("Someone(" + user.getUid() + ") try to login.");
        return ResUtil.ERROR("用户名或密码错误!");
    }
    @Override
    public ResJsonDTO adminLogin(UserDTO user){
        Admin admin = admRepo.findById(user.getUid()).orElse(null);
        String psw = user.getPassword();
        if (admin != null && admin.getPassword().equals(psw)) {
            user.setName(admin.getName());
            logService.addLog(new Log(
                    admin.getAid(),
                    admin.getName(),
                    "登录",
                    "成功",
                    null,
                    new Date()
            ));
            System.out.println("Admin:" + admin.getName() + " login.");
            return ResUtil.OK(TokenUtil.createToken(user, "Admin"));

        }
        logService.addLog(new Log(
                user.getUid(),
                user.getName(),
                "登录",
                "失败",
                null,
                new Date()
        ));
        System.out.println("Someone("+user.getUid()+") try to login.");
        return ResUtil.ERROR("用户名或密码错误!");
    }
    @Override
    public ResJsonDTO logout(String Token){
        System.out.println(Token+" Someone logout.");
        return ResUtil.OK();
    }
    @Override
    public ResJsonDTO getInfo(String Token){
        UserDTO user = TokenUtil.parseTokenId(Token);
        switch (user.getRole().charAt(0)) {
            case 'A':
                Admin admin = admRepo.findById(user.getUid()).orElse(null);
                if (admin == null) break;
                user.setName(admin.getName());
            case 'T':
                Teacher teacher = tchRepo.findById(user.getUid()).orElse(null);
                if (teacher == null) break;
                user.setName(teacher.getName());
            case 'S':
                Student student = stuRepo.findById(user.getUid()).orElse(null);
                if (student == null) break;
                user.setName(student.getName());
        }
        return ResUtil.OK(user);
    }

    @Override
    public ResJsonDTO createTeacher(Teacher teacher){
        if (teacher.getName()==null || teacher.getPassword()==null) {
            return ResUtil.ERROR("用户名或密码为空!");
        }
        if(tchRepo.existsById(teacher.getTid())){
            return ResUtil.ERROR("user already exits!");
        }
        OSClientV3 os = OSFactory.builderV3()
                .endpoint(properties.getKeystoneAPI())
                .credentials("e50212063663477c8e127206180a095e","asdfjkl")
                .scopeToProject(Identifier.byName("admin"), Identifier.byName("Default"))
                .authenticate();
        String ProjectName = Long.toString(teacher.getTid());
        Project project = os.identity().projects().create(Builders.project()//创建项目
                .name(ProjectName)
                .description(teacher.getName())
                .enabled(true)
                .build());
        User user = os.identity().users().create(Builders.user()//创建用户
                .name(ProjectName)
                .description(teacher.getName())
                .password(teacher.getPassword())
                .email(teacher.getEmail())
                .domainId("default")
                .build());
        os.identity().roles().grantProjectUserRole(project.getId(), user.getId(), "fd892bea52ba4dd18f4208de43c523dc");//授权用户


        teacher.setProjectID(project.getId());
        teacher.setUserID(user.getId());
        tchRepo.save(teacher);
        logService.addLog(new Log(
                null,
                "Admin",
                "添加教师用户",
                "成功",
                null,
                new Date()
        ));
        return ResUtil.OK();
    }

    @Override
    public ResJsonDTO getAllTeacher(QueryDTO query){
        ListDTO list = new ListDTO();
        List<UserDTO> userList = new ArrayList<>();
        List<Teacher> teachers = tchRepo.findAll();
        for (Teacher teacher : teachers) {
            userList.add(new UserDTO(
                    teacher.getTid(),
                    teacher.getPassword(),
                    teacher.getName(),
                    teacher.getEmail()
            ));
        }
        list.setUserList(userList);
        list.setTotal(teachers.size());
        System.out.println("管理员["+query.getAid()+"]获取教师列表成功");
        return ResUtil.OK(list);
    }
    @Override
    public ResJsonDTO getAllStudent(QueryDTO query){
        ListDTO list = new ListDTO();
        List<UserDTO> userList = new ArrayList<>();
        List<Student> students = stuRepo.findAll();
        for (Student student : students) {
            userList.add(new UserDTO(
                    student.getSid(),
                    student.getPassword(),
                    student.getName(),
                    student.getEmail()
            ));
        }
        list.setUserList(userList);
        list.setTotal(students.size());
        System.out.println("管理员["+query.getAid()+"]获取学生列表成功");
        return ResUtil.OK(list);
    }
    @Override
    public Student getStudentById(Long id){

        return null;
    }
    @Override
    public Teacher getTeacherById(Long id){

        return null;
    }
}
